Skip to content

Added ClientAssertionCredential to enable applications to authenticate with custom client assertions.#5789

Merged
ahsonkhan merged 7 commits intoAzure:mainfrom
ahsonkhan:ClientAssertionCredential
Jul 16, 2024
Merged

Added ClientAssertionCredential to enable applications to authenticate with custom client assertions.#5789
ahsonkhan merged 7 commits intoAzure:mainfrom
ahsonkhan:ClientAssertionCredential

Conversation

@ahsonkhan
Copy link
Copy Markdown
Contributor

@ahsonkhan ahsonkhan commented Jul 12, 2024

Part of #4905

@ahsonkhan ahsonkhan self-assigned this Jul 12, 2024
@ahsonkhan ahsonkhan marked this pull request as ready for review July 12, 2024 22:24
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp

ClientAssertionCredential::ClientAssertionCredential(
std::string tenantId,
std::string clientId,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one can be const ref, and it will not be a breaking change to change it back to by-value, if at some point we will be copying and storing one.

Suggested change
std::string clientId,
const std::string& clientId,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better not to design (or change) public surface area based on the implementation detail which could change.
I like the pattern for the ctor signatures being consistent with other credential types that we have.

I am not sure I see customer value by having some string params as const& and others as by-value, especially if we change those whenever the underlying implementation changes. What does the end user get out of that decision?
It's simpler to keep all params like these as std::string across all the creds.

ClientAssertionCredential::ClientAssertionCredential(
std::string tenantId,
std::string clientId,
std::function<std::string(Context const&)> const& assertionCallback,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is more efficient to take by-value and move:

Suggested change
std::function<std::string(Context const&)> const& assertionCallback,
std::function<std::string(Context const&)> assertionCallback,

(part 1/4)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you share more details on this. When is this more efficient vs take by-reference and why does std::function behave better as a move? Also, are there any consequences of doing an std::move (in general)? Why don't we do that everywhere?

Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated
Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated

IdentityLog::Write(
IdentityLog::Level::Warning,
AuthUnavailable + "See earlier " + GetCredentialName() + " log messages for details.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"See earlier ClientAssertionCredential log messages for details." - that's where that failure reason grouping and using GetCredentialName() at the start of the message will become handy, together with https://aka.ms/azsdk/cpp/identity/troubleshooting link that we include in some of our exceptions, and I think we should include it in the throw exception below too, using the similar patterns to existing credentials, they do this too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what you mean here. The pattern I used here is consistent with the existing credentials (environment, workload, etc.).

Look at this, as an example. This is almost identical to what we are doing here:

auto const AuthUnavailable = GetCredentialName() + " authentication unavailable. ";
IdentityLog::Write(
IdentityLog::Level::Warning,
AuthUnavailable + "See earlier " + GetCredentialName() + " log messages for details.");
throw AuthenticationException(
AuthUnavailable + "Environment variables are not fully configured.");

Comment thread sdk/identity/azure-identity/src/client_assertion_credential.cpp Outdated
Comment thread sdk/identity/azure-identity/test/ut/client_assertion_credential_test.cpp Outdated
{
IdentityLog::Write(
IdentityLog::Level::Warning,
"The assertionCallback must be a valid function that returns assertions for "
Copy link
Copy Markdown
Member

@antkmsft antkmsft Jul 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can be less general, i.e. not "valid function that returns", but "not be null".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure I see the value in being that specific. An "empty/no target" std::function would still fail. The invalid case isn't only if null is passed.

Copy link
Copy Markdown
Member

@antkmsft antkmsft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample is missing in sdk/identity/azure-identity/samples. BTW, sample for AzurePipelinesCredential is also missing there.

@ahsonkhan
Copy link
Copy Markdown
Contributor Author

Issue for samples: #5798

Samples will get added later, separately, after identity sample building is re-enabled. They were disabled here: #5754 (comment)

@ahsonkhan ahsonkhan merged commit 7e9906f into Azure:main Jul 16, 2024
@ahsonkhan ahsonkhan deleted the ClientAssertionCredential branch July 16, 2024 02:30
@ahsonkhan
Copy link
Copy Markdown
Contributor Author

Merging this to unblock the follow-up work I have on top that's required to fix #4905

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

3 participants